package space.panker916.controller;

import com.alibaba.fastjson.JSON;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import space.panker916.annotation.LoginRequired;
import space.panker916.pojo.R;
import space.panker916.pojo.User;
import space.panker916.service.FollowService;
import space.panker916.service.LikeService;
import space.panker916.service.UserService;
import space.panker916.utils.CommunityUtil;
import space.panker916.utils.HostHolder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import static space.panker916.utils.Constants.ENTITY_TYPE_USER;

@Controller
@RequestMapping("/user")
public class UserController {

    @Value("${community.path.upload}")
    private String uploadPath;              // 上传的路径

    @Value("${community.path.domain}")
    private String domain;                  // 域名

    @Value("${server.servlet.context-path}")
    private String contextPath;             // 项目名

    @Value("${qiniu.key.accessKey}")
    private String accessKey;

    @Value("${qiniu.key.secretKey}")
    private String secretKey;

    @Value("${qiniu.bucket.name}")
    private String bucketName;

    @Value("${qiniu.bucket.url}")
    private String bucketUrl;

    @Autowired
    private UserService userService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private FollowService followService;

    @Autowired
    private HostHolder hostHolder;

    @LoginRequired
    @GetMapping("/setting")
    public String getSettingPage(Model model) {
        // 上传文件名称
        String fileName = CommunityUtil.generateUUID();

        // 设置响应信息
        StringMap policy = new StringMap();
        policy.put("returnBody", JSON.toJSONString(new R(0)));

        // 生成上传凭证
        Auth auth = Auth.create(accessKey, secretKey);
        String uploadToken = auth.uploadToken(bucketName, fileName, 3600, policy);

        model.addAttribute("fileName", fileName);
        model.addAttribute("uploadToken", uploadToken);

        return "/site/setting";
    }

    @PostMapping("/header/url")
    @ResponseBody
    public R updateHeaderUrl(String fileName) {
        if (StringUtils.isBlank(fileName)) return new R(1, "文件名不能为空");

        String url = bucketUrl + "/" + fileName;
        userService.updateHeader(hostHolder.getUser().getId(), url);

        return new R(0);
    }

    /**
     * 本地的更新头像的方法，现在已废弃（因为文件都已经要上传到七牛云上面了）
     *
     * @param headerImage
     * @param model
     * @return
     * @throws IOException
     */
    @Deprecated
    @LoginRequired
    @PostMapping("/upload")
    public String uploadHeader(MultipartFile headerImage, Model model) throws IOException {
        if (headerImage == null) {
            model.addAttribute("error", "您还没有选择图片！");
            return "/site/setting";
        }

        String originalFilename = headerImage.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf('.'));
        if (StringUtils.isBlank(suffix)) {
            model.addAttribute("error", "图片的格式不正确！");
            return "/site/setting";
        }

        // 生成随机的文件名
        String fileName = CommunityUtil.generateUUID() + suffix;
        // 确定文件存放的路径
        File file = new File(uploadPath + "/" + fileName);
        // 存储文件
        headerImage.transferTo(file);

        // 更新当前用户的头像的路径（web访问路径）
        User user = hostHolder.getUser();
        String headUrl = domain + contextPath + "/user/header/" + fileName;
        userService.updateHeader(user.getId(), headUrl);

        return "redirect:/index";
    }

    @LoginRequired
    @PostMapping("/updatePassword")
    public String updatePassword(String oldPassword, String password, String surePassword, Model model) {

        if (StringUtils.isBlank(oldPassword)) {
            model.addAttribute("oldPasswordError", "请填写您的原密码！");
            return "/site/setting";
        }

        if (StringUtils.isBlank(password)) {
            model.addAttribute("passwordError", "请填写您的新密码！");
            return "/site/setting";
        }

        User user = hostHolder.getUser();
        if (!user.getPassword().equals(CommunityUtil.MD5(oldPassword + user.getSalt()))) {
            model.addAttribute("oldPasswordError", "您的原密码错误！");
            return "/site/setting";
        }

        if (password != surePassword) {
            model.addAttribute("surePasswordError", "您的确认密码与原密码不一致！");
            return "/site/setting";
        }

        userService.updatePassword(user.getId(), CommunityUtil.MD5(password + user.getSalt()));
        return "redirect:/index";
    }

    @Deprecated
    @GetMapping("/header/{fileName}")     // 在这个访问路径上响应一个 图像
    // 二进制数据，需要通过流，手动向浏览器输出
    public void getHeader(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {
        // 服务器存放路径
        fileName = uploadPath + "/" + fileName;
        // 文件的后缀
        String suffix = "image" + "/" + fileName.substring(fileName.lastIndexOf('.'));

        response.setContentType(suffix);
        ServletOutputStream outputStream = response.getOutputStream();      // 字节输出流
        FileInputStream inputStream = new FileInputStream(fileName);        // 字节输入流
        byte[] buffer = new byte[1024];         // 建立缓冲区
        int b = 0;                              // 建立游标
        while ((b = inputStream.read(buffer)) != -1) {      // 不等于 -1 就是在读数据，等于数据就是没读到数据（缓冲区满了）
            outputStream.write(buffer, 0, b);
        }

        inputStream.close();
    }

    // 个人主页
    @GetMapping("/profile/{userId}")
    public String getProfilePage(@PathVariable("userId") int UserId, Model model) {
        User user = userService.findUserById(UserId);
        if (user == null) throw new RuntimeException("查询用户个人主页时，该用户不存在");

        // 用户
        model.addAttribute("user", user);

        // 点赞数量
        int likeCount = likeService.findUserLikeCount(UserId);
        model.addAttribute("likeCount", likeCount);

        // 关注数量
        long followeeCount = followService.findFolloweeCount(UserId, ENTITY_TYPE_USER);
        model.addAttribute("followeeCount", followeeCount);

        // 粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER, UserId);
        model.addAttribute("followerCount", followerCount);

        // 是否已关注
        boolean hasFollowed = false;
        if (hostHolder.getUser() != null)
            hasFollowed = followService.hasFollowed(hostHolder.getUser().getId(), ENTITY_TYPE_USER, UserId);

        model.addAttribute("hasFollowed", hasFollowed);

        return "/site/profile";
    }
}
